package com.lnsoft.dqfs.test;

import com.lnsoft.dqfs.Application;
import com.lnsoft.dqfs.server.dao.DqfsDao;
import com.lnsoft.dqfs.server.dao.Yc;
import com.lnsoft.dqfs.server.util.MessageUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 数据手动入库 执行之前需要先修改下配置文件中连接数据的参数：（不然程序执行的时候，由于单个写入时间太长，容易导致超时错误） maxActive: 30
 * maxWait: 180000
 */
public class DataDb_handwork {
	private static final Logger logger = LoggerFactory.getLogger(DataDb_handwork.class);

	// 初始化线程池
	private static final ExecutorService pools = Executors.newFixedThreadPool(20);
	// 记录写文件到数据库的成功文件个数
	private static int fileTotal = 0;

	public static void main(String[] args) {
		// 初始化应用上下文
		ApplicationContext context = SpringApplication.run(Application.class, args);
		// 获取初始化好的数据库bean
		DqfsDao dqfsDao = context.getBean(DqfsDao.class);

//        String fileName = "C:\\Users\\Administrator\\.m2\\repository\\com\\lnsoft\\dqfs\\dqfs-server\\1.0\\4136_02019-3-11-5-36";
//        writeFile2DB(fileName,context);
		// 数据文件的所在的目录
//        String path = "D:\\工作相关（勿删）--贾来军\\201910\\20191018\\back-data";
		String path = "C:\\Users\\MAC\\Desktop\\远程办公--工作资料\\20200514--大气腐蚀--编写终端全量上传数据\\今日报文\\abc";
		// 获取目录下的所有的文件
		File[] files = listFiles(path, dqfsDao);

		DataDb_handwork dataDb_handwork = new DataDb_handwork();
		// 循环读取文件并写入数据库
		for (File file : files) {
//            writeFile2DB(file,dqfsDao);
			dataDb_handwork.execute(file, dqfsDao);
		}

	}

	// 获取目录下的所有文件
	public static File[] listFiles(String path, DqfsDao dqfsDao) {
		File dir = new File(path);
		File[] files = dir.listFiles();
		Integer index = 0;
		for (File file : files) {
			logger.info("index:{}", index++);
			logger.info("读取到的文件名称:{}", file.getName());
			Integer clientName = Integer.valueOf(file.getName().substring(0, 4));
			logger.info("终端号:{}", clientName);
			String clientId = dqfsDao.getIacmId(clientName, 2504);
			logger.info("终端ID:{}", clientId);
		}
		return files;
	}

	// 根据文件路径全名和应用上下文，将数据写入到数据库中
	public void writeFile2DB(File file, DqfsDao dqfsDao) {
		System.out.println("开始写入数据...");
		// 检查文件是否是具有完整遥测数据的文件
//        if (file.length() != 43201) {
//            System.out.println("数据不完整...");
//            return;
//        }

		List<Yc> list = null;
		RandomAccessFile randomAccessFile = null;
		try {
			// 包装打开的文件
			randomAccessFile = new RandomAccessFile(file, "rw");
			list = new ArrayList<>(200);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
			// 记录读取的行号
			int lineIndex = 0;
			while (true) {
				String line = randomAccessFile.readLine();
				// 行号自增
				lineIndex += 1;
				// 筛选哪些行的数据；此处是筛选135行以后的数据;正常情况下一个文件含有144行（条）数据;
//                if (lineIndex <= 135) {
//                    continue;
//                }
				// 检查行数据开头是否是真正的开头
				if (line == null || !line.startsWith("16")) {
					logger.info("忽略该行，数据异常，开头字符不是‘16’:", line);
					break;
				}
				logger.info(line);
				logger.info("该行数据字节长度:{}", line.length());
				line = line.replace("\n", "").trim();

				if (line.lastIndexOf("16,2") > 1) {
					line = line.substring(line.lastIndexOf("16,2"));
				}

				String[] datas = line.split(",");

				// 检查数据完整性，一组数据应该是34个字段
				if (datas.length != 34) {
					logger.info("忽略该行数据，字段不足34个：", line);
					continue;
				}

				Yc yc = new Yc();
				yc.setCjsj(sdf.format(sdf2.parse(datas[1])));
				yc.setTyndy(MessageUtil.upNanVal(datas[3].trim()));
				yc.setDcdy(MessageUtil.upNanVal(datas[5].trim()));
				yc.setJxwd(MessageUtil.upNanVal(datas[7].trim()));
				yc.setJxsd(MessageUtil.upNanVal(datas[9].trim()));
				yc.setGprs(MessageUtil.upNanVal(datas[11].trim()));
				yc.setHjwd(MessageUtil.upNanVal(datas[13].trim()));
				yc.setHjsd(MessageUtil.upNanVal(datas[15].trim()));
				yc.setSond(MessageUtil.upNanVal(datas[17].trim()));
				yc.setYf(MessageUtil.upNanVal(datas[19].trim()));
				yc.setBy1(MessageUtil.upNanVal(datas[21].trim()));
				yc.setBy2(MessageUtil.upNanVal(datas[23].trim()));
				yc.setBy3(MessageUtil.upNanVal(datas[25].trim()));
				yc.setZndl(MessageUtil.upNanVal(datas[27].trim()));
				yc.setCudl(MessageUtil.upNanVal(datas[29].trim()));
				yc.setAldl(MessageUtil.upNanVal(datas[31].trim()));
				yc.setFedl(MessageUtil.upNanVal(datas[33].trim()));
				// 构造结构化的、将要写入数据库的数据
				list.add(yc);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (randomAccessFile != null) {
				try {
					randomAccessFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		// 记录开始写入的时间
		long time = System.currentTimeMillis();
		if (list != null) {
			final List<Yc> ycList = list;
			logger.info("文件名:{}", file.getName());
			Integer clientName = Integer.valueOf(file.getName().substring(0, 4));
			logger.info("终端号:{}", clientName);
			String clientId = dqfsDao.getIacmId(clientName, 2504);
			logger.info("终端ID:{}", clientId);
			// 执行写入
			dqfsDao.saveYcList(clientName, 2504, clientId, ycList);
			// 更新在线时间
//            dqfsDao.updateIacmDownTime(clientId);

		}
		// 打印该次写入所用时间
		System.out.println(" 耗时:" + (System.currentTimeMillis() - time));
		// 打印已经成功写入的文件总数
		logger.info("写入数据库的文件总数:{}", ++fileTotal);

		return;
	}

	// 实现线程池的run方法
	public void execute(File file, DqfsDao dqfsDao) {
		pools.execute(new Runnable() {
			@Override
			public void run() {
				writeFile2DB(file, dqfsDao);
			}
		});
	}
}
